home *** CD-ROM | disk | FTP | other *** search
- Path: magnus.acs.ohio-state.edu!csn!ub!newserve!rebecca!rpi!not-for-mail
- From: Richard Wells <rdwells@mmm.com>
- Newsgroups: comp.lang.c++,comp.lang.c++.moderated,comp.lang.c.moderated
- Subject: Re: Q: Rigorous coding using #if !defined(...) and #include
- Date: 2 Feb 1996 16:08:28 -0000
- Organization: 3M Company
- Sender: cppmods@netlab.cs.rpi.edu
- Approved: devitto@ferndown.ate.slb.com
- Message-ID: <4etcts$l50@netlab.cs.rpi.edu>
- References: <4eo1fs$rr3@netlab.cs.rpi.edu>
- NNTP-Posting-Host: netlab.cs.rpi.edu
- X-Original-Date: Fri, 02 Feb 1996 09:43:24 -0600
-
- (I see the moderator(s) allowed the crossposting for the
- first message, so I'll keep the full list of newsgroups.
- I would argue that this applies to C as well as C++ if you
- just replace "class" with "struct" in the code below and
- make the other obvious necessary syntactical changes.)
-
- David Carr wrote:
- >
- > In header files, I have used the notation;
- >
- > #if !defined (__MYCLASS_H)
- > #define (__MYCLASS_H)
- >
- > #include "Other.h"
- >
- > class MyClass
- > {
- > ...// Uses something in Other.h
- > };
- >
- > #endif
- >
- > The problem is this. I have another class;
- >
- > #if !defined (__OTHER_H)
- > #define (__OTHER_H)
- >
- > #include "MyClass.h"
- >
- > class Other
- > {
- > ...// Uses something in MyClass.h
- > };
- >
- > #endif
- >
- > and in my source for MyClass.cpp, MyClass.h is obviously
- > included. Now,
- > when I try to compile MyClass.cpp, MyClass.h is included and
- > __MYCLASS_H
- > becomes defined. Then, MyClass.h #includes Other.h, thus
- > defining __OTHER_H.
- > Now, Other.h #includes MyClass.h. As __MYCLASS_H has already
- > been defined,
- > the code in MyClass.h is not included. Returning to Other.h,
- > this code
- > references something in MyClass.h (i.e. its class) and a
- > compiler error is
- > generated because the symbol/identifier/whatever is unknown.
- >
- > What is the preferred method for writing rigorous code and
- > solving this
- > problem?
- > Any suggestions as to how to make H files a complete interface?
-
- I find that this can generally be avoided by taking advantage
- of the fact that you can use pointers to incomplete types (someone
- please correct me if this not the proper C/C++ terminology). For
- example, to flesh out your example a little:
-
- #if !defined (__MYCLASS_H)
- #define (__MYCLASS_H)
-
- #include "Other.h"
-
- class MyClass
- {
- Other *foo;
- };
-
- #endif
-
- and in another header
-
- #if !defined (__OTHER_H)
- #define (__OTHER_H)
-
- #include "MyClass.h"
-
- class Other
- {
- MyClass *bar;
- };
-
- #endif
-
- The #include statements within the headers can be replaced
- by "class Other;" and "class MyCLass;", to get:
-
- #if !defined (__MYCLASS_H)
- #define (__MYCLASS_H)
-
- class Other; // #include replaced by incomplete type
-
- class MyClass
- {
- Other *foo;
- };
-
- #endif
-
- and
-
- #if !defined (__OTHER_H)
- #define (__OTHER_H)
-
- class MyClass; // #include replaced by incomplete type
-
- class Other
- {
- MyClass *bar;
- };
-
- #endif
-
- I have yet to run into circumstances where this does not
- avoid the situation.
-
- In fact, I tend to use incomplete types wherever possible
- in place of #include. It keeps compile times down a little,
- and IMHO provides for better information hiding. That is,
- in the above example, class Other needs to know that class
- MyClass exists, but probably shouldn't be privy to its
- internal details, so shouldn't need to #include its header.
-
- Just to bore y'all a little longer, if one of the classes
- actually contains an instance of the other rather than a
- pointer to an instance, than it is necessary to include
- the proper header. For example:
-
- #if !defined (__MYCLASS_H)
- #define (__MYCLASS_H)
-
- class Other;
-
- class MyClass
- {
- Other *foo; // still a pointer
- };
-
- #endif
-
- and
-
- #if !defined (__OTHER_H)
- #define (__OTHER_H)
-
- #include "MyClass.h" // need the full definition
-
- class Other
- {
- MyClass bar; // NOT a pointer
- };
-
- #endif
-
- Hope this helps.
-
- [ Articles to moderate: mailto:c++-submit@netlab.cs.rpi.edu ]
- [ Read the C++ FAQ: http://www.connobj.com/cpp/cppfaq.htm ]
- [ Moderation policy: http://www.connobj.com/cpp/guide.htm ]
- [ Comments? mailto:c++-request@netlab.cs.rpi.edu ]
-